﻿Imports System.IO.IsolatedStorage
Imports System.IO

#If IRONPYTHON_AVAILABLE Then
Imports IronPython.Hosting
#End If

#If IRONRUBY_AVAILABLE Then
Imports IronRuby.StandardLibrary.BigDecimal
Imports Microsoft.Scripting.Hosting
Imports IronRuby
Imports IronRuby.StandardLibrary
#End If

Imports System.Runtime.CompilerServices

Public Class ScriptTaskOnErrorEventArgs
    Inherits EventArgs

    Public Property [Error]() As New Exception

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal e As Exception)
        Me.Error = e
    End Sub

End Class

Public Class ScriptTask

    Public Property Name() As String
    Public Property CommitTime() As DateTime
    Public Property Script() As String
    Public Property ScriptType() As String
    Public Property Result() As Object
    Public Property LastError() As Exception

    Private Shared Property Engine() As ScriptEngine

    Public Event OnError(ByVal sender As Object, ByVal e As ScriptTaskOnErrorEventArgs)

    Public Sub New(ByVal n As String, Optional ByVal s As String = "")
        If n.ToLower().EndsWith(".rb") Then
            Me.ScriptType = "Ruby"
#If IRONRUBY_AVAILABLE Then
            ScriptTask.Engine = Ruby.CreateEngine()
            Me.LoadAssembly(GetType(BigDecimal).Assembly)
#End If
        ElseIf n.ToLower().EndsWith(".py") Then
            Me.ScriptType = "Python"
#If IRONPYTHON_AVAILABLE Then
            Me.Engine = Python.CreateEngine()
#End If
        Else
            Throw New Exception("Unsupported script type.")
        End If
        Me.Name = n
        Me.Script = s
    End Sub

    Public Sub LoadAssembly(ByVal assembly As System.Reflection.Assembly)
        Engine.Runtime.LoadAssembly(assembly)
    End Sub

    Public Sub LoadScriptFromIsolatedStorage(ByVal path As String, ByVal fileStorage As IsolatedStorageFile)
        Try
            Using fs = fileStorage.OpenFile(path, FileMode.Open)
                Using sr As New IO.StreamReader(fs)
                    Me.Script = sr.ReadToEnd()
                    sr.Close()
                End Using
                fs.Close()
            End Using
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Public Function Excute(ByVal ParamArray args() As Tuple(Of String, Object)) As Boolean
        Try
            If Me.Script = "" Then
                Return True
            End If
            For Each var In args
                Engine.Runtime.Globals.SetVariable(var.Item1, var.Item2)
            Next
            Me.Result = Engine.Execute(Me.Script)
            Return True
        Catch ex As Exception
            Me.LastError = ex
            RaiseEvent OnError(Me, New ScriptTaskOnErrorEventArgs(ex))
            Return False
        End Try
    End Function

End Class